﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.Windows.Forms.VisualStyles;
using System.Drawing.Drawing2D;
/// <summary>
/// GroupBox control that provides functionality to 
/// allow it to be collapsed.
/// </summary>
namespace eTMS.Controls
{


    [ToolboxBitmap(typeof(CustomGroupBox))]
    public partial class CustomGroupBox : System.Windows.Forms.GroupBox
    {
        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
        #region Component Designer generated code
        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomGroupBox));
            this.SuspendLayout();
            // 
            // CustomGroupBox
            // 
            this.Name = "CustomGroupBox";
            this.ResumeLayout(false);
        }
        #endregion
        #region Fields
        private Rectangle m_toggleRect = new Rectangle(8, 1, 16, 16);
        private Boolean m_collapsed = false;
        private Boolean m_bResizingFromCollapse = false;
        private const int m_collapsedHeight = 20;
        private Size m_FullSize = Size.Empty;
        private PushButtonState buttonState = PushButtonState.Normal;
        #endregion
        #region Events & Delegates
        /// <summary>Fired when the Collapse Toggle button is pressed</summary>
        public delegate void CollapseBoxClickedEventHandler(object sender);
        public event CollapseBoxClickedEventHandler CollapseBoxClickedEvent;
        #endregion
        #region Constructor
        public CustomGroupBox()
        {
            InitializeComponent();
            this.BackColor = Color.FromArgb(255, 255, 255);
            this.StartGradientColor = Color.FromArgb(215, 229, 247);
            this.EndGradientColor = Color.FromArgb(186, 211, 245);
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true);
            //this.BorderColor = Color.RoyalBlue;
        }
        #endregion
        #region Public Properties
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int FullHeight
        {
            get { return m_FullSize.Height; }
        }
        [DefaultValue(false), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public bool IsCollapsed
        {
            get { return m_collapsed; }
            set
            {
                if (value != m_collapsed)
                {
                    m_collapsed = value;
                    if (!value)
                        // Expand
                        this.Size = m_FullSize;
                    else
                    {
                        // Collapse
                        m_bResizingFromCollapse = true;
                        this.Height = m_collapsedHeight;
                        m_bResizingFromCollapse = false;
                    }
                    foreach (Control c in Controls)
                        c.Visible = !value;
                    Invalidate();
                }
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int CollapsedHeight
        {
            get { return m_collapsedHeight; }
        }
        #endregion
        #region Overrides
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (m_toggleRect.Contains(e.Location))
            {
                buttonState = PushButtonState.Pressed;
                this.Invalidate(m_toggleRect);
            }
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (m_toggleRect.Contains(e.Location))
            {
                buttonState = PushButtonState.Hot;
                ToggleCollapsed();
            }
            else
            {
                buttonState = PushButtonState.Normal;
                this.Invalidate(m_toggleRect);
                base.OnMouseUp(e);
            }
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (m_toggleRect.Contains(e.Location))
            {
                if (buttonState != PushButtonState.Pressed)
                {
                    if (buttonState != PushButtonState.Hot)
                    {
                        buttonState = PushButtonState.Hot;
                        this.Invalidate(m_toggleRect);
                    }
                }
            }
            else
            {
                if (buttonState != PushButtonState.Normal)
                {
                    buttonState = PushButtonState.Normal;
                    this.Invalidate(m_toggleRect);
                }
            }
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            DrawBackGround(e.Graphics);
            DrawGroupBox(e.Graphics);
            DrawToggleButton(e.Graphics);
        }
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            HandleResize();
        }
        #endregion
        #region Implimentation
        void DrawGroupBox(Graphics g)
        {
            // Get windows to draw the GroupBox
            Rectangle bounds = new Rectangle(ClientRectangle.X, ClientRectangle.Y + 6, ClientRectangle.Width, ClientRectangle.Height - 6);
            GroupBoxRenderer.DrawGroupBox(g, bounds, "", this.Font, Enabled ? GroupBoxState.Normal : GroupBoxState.Disabled);
            // Text Formating positioning & Size
            StringFormat sf = new StringFormat();
            int i_textPos = (bounds.X + 8) + m_toggleRect.Width + 2;
            int i_textSize = (int)g.MeasureString(Text, this.Font).Width;
            i_textSize = i_textSize < 1 ? 1 : i_textSize;
            int i_endPos = i_textPos + i_textSize + 1;
            // Draw a line to cover the GroupBox border where the text will sit
            //Pen p = new Pen(this.BackColor, 4);
            //g.DrawLine(p, i_textPos, bounds.Y, i_endPos, bounds.Y);
            //p.Dispose();
            // Draw the GroupBox text
            using (SolidBrush drawBrush = new SolidBrush(this.ForeColor))
                g.DrawString(Text, this.Font, drawBrush, i_textPos, 0);
        }
        void DrawToggleButton(Graphics g)
        {
            if (IsCollapsed)
                DrawPlus(g, m_toggleRect);
            else
                DrawMinus(g, m_toggleRect);
        }
        void DrawPlus(Graphics g, Rectangle m_toggleRect)
        {
            ButtonRenderer.DrawButton(g, m_toggleRect, "", this.Font, false, buttonState);
            Pen pen = SystemPens.ControlText;
            //g.DrawRectangle(pen, m_toggleRect);
            g.DrawLine(pen, m_toggleRect.X + 4, m_toggleRect.Y + m_toggleRect.Height / 2, m_toggleRect.X + m_toggleRect.Width - 4, m_toggleRect.Y + m_toggleRect.Height / 2);
            g.DrawLine(pen, m_toggleRect.X + m_toggleRect.Width / 2, m_toggleRect.Y + 4, m_toggleRect.X + m_toggleRect.Width / 2, m_toggleRect.Y + m_toggleRect.Height - 4);
            //ButtonRenderer.DrawButton(g, m_toggleRect, "+", this.Font, false, PushButtonState.Normal);
        }
        void DrawMinus(Graphics g, Rectangle m_toggleRect)
        {
            ButtonRenderer.DrawButton(g, m_toggleRect, "", this.Font, false, buttonState);
            Pen pen = SystemPens.ControlText;
            //g.DrawRectangle(pen, m_toggleRect);
            g.DrawLine(pen, m_toggleRect.X + 4, m_toggleRect.Y + m_toggleRect.Height / 2, m_toggleRect.X + m_toggleRect.Width - 4, m_toggleRect.Y + m_toggleRect.Height / 2);
            //ButtonRenderer.DrawButton(g, m_toggleRect, "-", this.Font, false, PushButtonState.Normal);
        }
        public void ToggleCollapsed()
        {
            IsCollapsed = !IsCollapsed;
            if (CollapseBoxClickedEvent != null)
                CollapseBoxClickedEvent(this);
            this.Invalidate();
        }
        void HandleResize()
        {
            if (!m_bResizingFromCollapse && !m_collapsed)
                m_FullSize = this.Size;
        }



        private Color endgradColor = Color.FromArgb(220, 220, 230);
        private Color startgradColor = Color.FromArgb(220, 230, 240);
        private LinearGradientMode gradientMode = LinearGradientMode.Vertical;
        private float gradPercent = 0.5f;
        public LinearGradientMode GradientMode
        {
            get
            {
                return gradientMode;
            }
            set
            {
                gradientMode = value;
                this.Invalidate();
            }
        }
        public float GradientPercent
        {
            get
            {
                return gradPercent;
            }
            set
            {
                gradPercent = value;
                this.Invalidate();
            }
        }
        public Color StartGradientColor
        {
            get
            {
                return startgradColor;
            }
            set
            {
                startgradColor = value;
                this.Invalidate();
            }
        }
        public Color EndGradientColor
        {
            get
            {
                return endgradColor;
            }
            set
            {
                endgradColor = value;
                this.Invalidate();
            }
        }

        private void DrawBackGround(Graphics g)
        {
            // Create a rectangle
            g.Clear(this.BackColor);
            Rectangle rect = this.ClientRectangle;
            if (rect.Height == 0) return;
            if (rect.Width == 0) return;
            // Create a linear gradient brush
            LinearGradientBrush rgBrush =
                new LinearGradientBrush(
                rect, this.startgradColor, this.endgradColor, gradientMode
            );					// Set signma bell shape
            rgBrush.SetSigmaBellShape(gradPercent, 1.0f);
            // Fill rectangle again
            g.FillRectangle(rgBrush, rect);
            rgBrush.Dispose();

        }

        #endregion
    }

}